﻿/**
* Класс реализует управление кешем, это нужно для предварительной загрузки
* изображения, swf файлов и т.д., работает по принципу стека, загрузка последовательная
* 
* @author Firsoff Maxim, ICQ:235859730, email: firsoff_maxim@mail.ru
* @version 0.1/12.02.2008 9:23
*/

package ru.vega_int.firsoff.as3 
{
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.errors.IOError;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.EventDispatcher;
	import flash.net.URLLoader;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.display.LoaderInfo;
	
	import ru.vega_int.firsoff.as3.events.CacheManagerEvents;

	public class CacheManager extends EventDispatcher
	{
		//	PROPERTIES
		public var lastLoadedUrl:String;	//	последний загруженный урл
		public var loaded:uint;
		public var total:uint;
		
		private var _stack:Array;			//	стек загрузок
		private var _loaders:Array;			//	массив лоадеров
		private var _loadComplete:Boolean;	//	загрузка окончена?
		private var _strategy:String;
		
		public static const FULL_LOAD:String = 'full_load';
		public static const PARALLEL_LOADING:String = 'parallel_loading';
		public static const STEPBYSTEP_LOADING:String = 'stepbystep_loading';
		//private var 
		public function CacheManager(strategy:String = 'parallel_loading') 
		{
			_strategy = strategy;
			init();
		};
		
		//	METHODS
		
		//	private
		private function init():void
		{
			lastLoadedUrl = null;
			_stack = new Array();
			_loaders = new Array();
			_loadComplete = false;
		};
		
		private function loadNextFile():void
		{
			var loader:Loader = new Loader();
			var request:URLRequest = new URLRequest(_stack[loaded]);
			_loaders.push(loader);
			//	формируем слушателей
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, handleError);
			loader.load(request);
		};
		
		//	public
		public function load(images:Array) : void
		{
			
			destroy();
			loaded = 0;
			total = images.length;
			_stack = images;
			if (_strategy == PARALLEL_LOADING)
			{
				for (var i:int = 0; i < _stack.length; i++) 
				{
					var loader:Loader = new Loader();
					var request:URLRequest = new URLRequest(_stack[i]);
					_loaders.push(loader);
					
					//	формируем слушателей
					loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleComplete);
					loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, handleError);
					//loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
					loader.load(request);
					
				};
			}
			else 
			{
				//trace('LOAD')
				loadNextFile();
			};
		};
		
		
		
		
		public function destroy() : void
		{
			
			for (var i:int = 0; i < _loaders.length; i++) 
			{
				var l:Loader = Loader(_loaders[i]);
				l.contentLoaderInfo.removeEventListener(Event.COMPLETE, handleComplete);
				l.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, handleError);
				try 
				{
					//trace('destroy');
					l.close();
					l.unload();
				}
				catch (e:Error)
				{
					
				};
				
			};
			_loaders = new Array();
		};
		//	HANDLERS
		
		private function handleComplete(e:Event):void 
		{
			loaded++;
			
			lastLoadedUrl = LoaderInfo(e.target).url;
			if (_strategy == STEPBYSTEP_LOADING)
			{
				//trace(loaded, total)
				if (loaded < total)
				{
					loadNextFile();
				}
			}
			if (loaded == total)
			{
				this.dispatchEvent(new CacheManagerEvents(CacheManagerEvents.FULL_LOAD));
			};
		};
		
		private function handleError(e:IOErrorEvent):void 
		{
			loaded++;
			if (loaded == total)
			{
				this.dispatchEvent(new CacheManagerEvents(CacheManagerEvents.ERROR));
			};
		};
		
		public function get strategy():String { return _strategy; };
		
	};
	
};
